[9-Gin路由高级]
一 路由分组
routes group是为了管理一些相同的URL
https://gin-gonic.com/zh-cn/docs/examples/grouping-routes/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| package main
import ( "fmt" "github.com/gin-gonic/gin" )
func main() { r := gin.Default() v1 := r.Group("/v1") { v1.GET("/login", login) v1.GET("submit", submit) } v2 := r.Group("/v2")
v2.POST("/login", login) v2.POST("/submit", submit)
r.Run(":8000") }
func login(c *gin.Context) { name := c.DefaultQuery("name", "lqz") c.String(200, fmt.Sprintf("hello %s\n", name)) }
func submit(c *gin.Context) { name := c.DefaultQuery("name", "pyy") c.String(200, fmt.Sprintf("hello %s\n", name)) }
|
测试
1 2 3 4 5
| get请求:127.0.0.1:8000/v1/login post请求:127.0.0.1:8000/v1/submit
get请求:127.0.0.1:8000/v2/login post请求:127.0.0.1:8000/v2/submit
|
二 路由拆分与注册
2.1 基本路由注册
适用于路由比较少的简单项目
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| package main
import ( "net/http"
"github.com/gin-gonic/gin" )
func helloHandler(c *gin.Context) { c.JSON(http.StatusOK, gin.H{ "message": "Hello world!", }) }
func main() { r := gin.Default() r.GET("/hello", helloHandler) r.Run() }
|
2.2 路由拆分成单独文件或包
当项目的规模增大后就不太适合继续在项目的main.go
文件中去实现路由注册相关逻辑了,我们会倾向于把路由部分的代码都拆分出来,形成一个单独的文件或包
2.2.1 拆分到单独文件中(不使用分组)
目录结构

routers.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| package main import ( "net/http" "github.com/gin-gonic/gin" )
func helloHandler(c *gin.Context) { c.JSON(http.StatusOK, gin.H{ "msg": "www.liuqingzheng.top", }) } func testHandler(c *gin.Context) { c.JSON(http.StatusOK, gin.H{ "status":100, "msg": "hello world", }) }
func initRouter() *gin.Engine { r := gin.Default() r.GET("/hello", helloHandler) r.GET("/test", testHandler) return r }
|
main.go
1 2 3 4 5 6 7 8 9 10
| package main
func main() { r := initRouter() r.Run() }
http:
|
2.2.2 拆分到包中
目录结构

routers/routers.go
routers/routers.go
需要注意此时initRouter需要改成首字母大写:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| package routers import ( "net/http"
"github.com/gin-gonic/gin" )
func helloHandler(c *gin.Context) { c.JSON(http.StatusOK, gin.H{ "msg": "www.liuqingzheng.top", }) } func testHandler(c *gin.Context) { c.JSON(http.StatusOK, gin.H{ "status":100, "msg": "hello world", }) }
func InitRouter() *gin.Engine { r := gin.Default() r.GET("/hello", helloHandler) r.GET("/test", testHandler) return r }
|
main.go
1 2 3 4 5 6 7 8
| package main
import "gin_test/routers"
func main() { r := routers.InitRouter() r.Run() }
|
2.3 路由拆分成多个文件
单独的一个routers
文件或包已经满足不了我们的需求了
目录结构

routers/goods.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| package routers
import ( "github.com/gin-gonic/gin" "net/http" )
func LoadGoodsRouters(r *gin.Engine) { good := r.Group("/good") { good.GET("/", goodHandler) good.GET("/goodlist", goodlistHandler) good.GET("/updategood", updategoodHandler) } } func goodHandler(c *gin.Context) { c.JSON(http.StatusOK, gin.H{ "msg": "www.liuqingzheng.top", }) }
func goodlistHandler(c *gin.Context) { c.String(http.StatusOK, "goodlistHandler") } func updategoodHandler(c *gin.Context) { c.String(http.StatusOK, "updategoodHandler") }
|
routers/order.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| package routers
import ( "github.com/gin-gonic/gin" "net/http" )
func LoadOrderRouters(r *gin.Engine) { order := r.Group("/order") { order.GET("/", orderHandler) order.GET("/orderlist", orderlistHandler) order.GET("/updateorder", updateorderHandler) } } func orderHandler(c *gin.Context) { c.JSON(http.StatusOK, gin.H{ "msg": "www.liuqingzheng.top", }) }
func orderlistHandler(c *gin.Context) { c.String(http.StatusOK, "orderlistHandler") } func updateorderHandler(c *gin.Context) { c.String(http.StatusOK, "updateorderHandler") }
|
routers/user.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| package routers
import ( "github.com/gin-gonic/gin" "net/http" )
func LoadUserRouters(r *gin.Engine) { user := r.Group("/user") { user.GET("/", userHandler) user.GET("/userlist", userlistHandler) user.GET("/updateuser", updateuserHandler) } } func userHandler(c *gin.Context) { c.JSON(http.StatusOK, gin.H{ "msg": "www.liuqingzheng.top", }) }
func userlistHandler(c *gin.Context) { c.String(http.StatusOK, "userlistHandler") } func updateuserHandler(c *gin.Context) { c.String(http.StatusOK, "updateuserHandler") }
|
main.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| package main
import ( "gin_test/routers" "github.com/gin-gonic/gin" )
func main() { r := gin.Default() routers.LoadGoodsRouters(r) routers.LoadOrderRouters(r) routers.LoadUserRouters(r) r.Run() }
|
2.4 路由拆分到不同的APP
有时候项目规模实在太大,那么我们就更倾向于把业务拆分的更详细一些,例如把不同的业务代码拆分成不同的APP。
因此我们在项目目录下单独定义一个app
目录,用来存放我们不同业务线的代码文件,这样就很容易进行横向扩展。大致目录结构如下:

app01/shop/handler.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| package shop
import ( "github.com/gin-gonic/gin" "net/http" )
func shopHandler(c *gin.Context) { c.String(http.StatusOK, "shopHandler") }
func shopInfoHandler(c *gin.Context) { c.String(http.StatusOK, "shopInfoHandler") }
|
app01/shop/router.go
1 2 3 4 5 6 7 8
| package shop
import "github.com/gin-gonic/gin"
func Routers(e *gin.Engine) { e.GET("/shop", shopHandler) e.GET("/shopinfo", shopInfoHandler) }
|
app01/user/handler.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| package user
import ( "github.com/gin-gonic/gin" "net/http" )
func userHandler(c *gin.Context) { c.String(http.StatusOK, "userHandler") }
func userInfoHandler(c *gin.Context) { c.String(http.StatusOK, "userInfoHandler") }
|
app01/user/router.go
1 2 3 4 5 6 7 8 9
| package user
import "github.com/gin-gonic/gin"
func Routers(e *gin.Engine) { e.GET("/user", userHandler) e.GET("/userinfo", userInfoHandler) }
|
routers/routers.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| package routers
import "github.com/gin-gonic/gin"
type Option func(engine *gin.Engine) var options=[]Option{}
func Include(opts ...Option) { options=append(options,opts...) }
func Init()*gin.Engine { r:=gin.New() for _,opt:=range options{ opt(r) } return r }
|
main.go
1 2 3 4 5 6 7 8 9 10 11 12 13
| package main
import ( "gin_test/app01/shop" "gin_test/app01/user" "gin_test/routers" )
func main() { routers.Include(shop.Routers,user.Routers) r:=routers.Init() r.Run() }
|